/*****************************************************************************
* File Name: main.c
*
* Version: 1.0
*
* Description:
* Thi file implements the application logic include state machine handling
*
* Note:
* None
*
* Owner: MRAO
*
* Related Document:
* PRoC BLE Datasheet
*
* Hardware Dependency:
* PRoC BLE Family of Devices
*
* Code Tested With:
* 1. PSoC Creator 3.1 
* 2. ARM GCC 4.8.4
******************************************************************************
* Copyright (2015), Cypress Semiconductor Corporation.
******************************************************************************
* This software is owned by Cypress Semiconductor Corporation (Cypress) and is
* protected by and subject to worldwide patent protection (United States and
* foreign), United States copyright laws and international treaty provisions.
* Cypress hereby grants to licensee a personal, non-exclusive, non-transferable
* license to copy, use, modify, create derivative works of, and compile the
* Cypress Source Code and derivative works for the sole purpose of creating
* custom software in support of licensee product to be used only in conjunction
* with a Cypress integrated circuit as specified in the applicable agreement.
* Any reproduction, modification, translation, compilation, or representation of
* this software except as specified above is prohibited without the express
* written permission of Cypress.
*
* Disclaimer: CYPRESS MAKES NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, WITH
* REGARD TO THIS MATERIAL, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 
* Cypress reserves the right to make changes without further notice to the
* materials described herein. Cypress does not assume any liability arising out
* of the application or use of any product or circuit described herein. Cypress
* does not authorize its products for use as critical components in life-support
* systems where a malfunction or failure may reasonably be expected to result in
* significant injury to the user. The inclusion of Cypress' product in a life-
* support systems application implies that the manufacturer assumes all risk of
* such use and in doing so indemnifies Cypress against all charges. Use may be
* limited by and subject to the applicable Cypress software license agreement.
*****************************************************************************/
#include "main.h"
#include "device.h"
#include "visual_scop.h"

/* Variable to indicate the device state */
Device_State deviceState;
/* Variable to indicate activity is detected in low power mode */
uint8 isActitiyDetected;
/* Variable to indicate the low battery detection */
uint8 isBatteryLow;

/*****************************************************************************
* Function Name: Device_FW_Init()
******************************************************************************
* Summary:
* This function does the device initialization
*
* Parameters:
* None
*
* Return:
* None
*
* Theory:
* It initializes timer, watch dog timer and debug modules. It also initializes
* the device. It is responsibility of the device module to indicate if 
* battery is low.
*
* Side Effects:
* deviceState is updated
* 
* Note:
* None
*****************************************************************************/
static void Device_FW_Init(void)
{    
    deviceState = DEVICE_ACTIVE;
    CyGlobalIntEnable;
    /* Device_Timer_CallBack is registered with the timer module. The callback function 
     * is used for updating the LED brightness */
    Timer_Init(Device_Timer_Callback);
    Watch_Dog_Timer_Init(DEVICE_WATCH_DOG_TIMER_COUNTER0_VALUE);
    #ifndef DEBUG_PIN
    Debug_Print_Start(DEBUG_MESSAGE_LEVEL_4);
    #else
    Visual_Scop_Start();
    #endif
    Device_Init();
    if(isBatteryLow)
    {
        deviceState = DEVICE_SHUTDOWN;
    }
}

/*****************************************************************************
* Function Name: Device_FW_Active()
******************************************************************************
* Summary:
* This function performs the activity in the active mode
*
* Parameters:
* None
*
* Return:
* None
*
* Theory:
* The timer is configured to tick every 1 msec. All the modules should 
* be developed after considering this into account
*
* Side Effects:
* deviceState is updated
* 
* Note:
* None
*****************************************************************************/
static void Device_FW_Active(void)
{
    isActitiyDetected = false;
    Timer_Active();
    /* Device_Active function should exit only on low battery condition or  
     * on activity timeout */
    Device_Active();
    if(isBatteryLow)
    {
        deviceState = DEVICE_SHUTDOWN;
    }
    else
    {
        deviceState = DEVICE_IDLE;
    }
}

/*****************************************************************************
* Function Name: Device_FW_Idle()
******************************************************************************
* Summary:
* This function perform the activity in the idle mode
*
* Parameters:
* None
*
* Return:
* None
*
* Theory:
* The timer is configured to tick every to 125 msec. Module should be developed 
* considering this into account
*
* Side Effects:
* deviceState is updated
* 
* Note:
* None
*****************************************************************************/
static void Device_FW_Idle(void)
{
    Timer_Idle();
    /* Device_Idle() function should exit only on low battery condition 
     * or on user activity or on idle time out */
    Device_Idle();
    if(isBatteryLow)
    {
        deviceState = DEVICE_SHUTDOWN;
    }
    else if(isActitiyDetected)
    {
        deviceState = DEVICE_ACTIVE;
    }
    else
    {
        deviceState = DEVICE_SLEEP;
    }
}

/*****************************************************************************
* Function Name: Device_FW_Sleep()
******************************************************************************
* Summary:
* This function perform the activity in the sleep mode
*
* Parameters:
* None
*
* Return:
* None
*
* Theory:
* The timer is configured to tick every 250 msec. Module should be developed 
* considering this into account
*
* Side Effects:
* deviceState is updated
* 
* Note:
* None
*****************************************************************************/
static void Device_FW_Sleep(void)
{
    Timer_Sleep();
    /* Device_Sleep() function should exit only on low battery condition
     * or on user activity or on sleep timeout */
    Device_Sleep();
    if(isBatteryLow)
    {
        deviceState = DEVICE_SHUTDOWN;
    }
    else if(isActitiyDetected)
    {
        deviceState = DEVICE_ACTIVE;
    }
    else
    {
#ifdef ENABLE_SYSTEM_DEEP_SLEEP
        deviceState = DEVICE_DEEP_SLEEP;
#endif /* ENABLE_SYSTEM_DEEP_SLEEP */
    }
}

#ifdef ENABLE_SYSTEM_DEEP_SLEEP
/*****************************************************************************
* Function Name: Device_FW_DeepSleep()
******************************************************************************
* Summary:
* This function performs the activity in the deep sleep mode
*
* Parameters:
* None
*
* Return:
* None
*
* Theory:
* The timer is configured for ticking every 500ms. All modules developed need 
* to be developed considering this into account
*
* Side Effects:
* deviceState is updated
* 
* Note:
* None
*****************************************************************************/
static void Device_FW_DeepSleep(void)
{
    Timer_Deep_Sleep();
    Device_DeepSleep();
    if(isBatteryLow)
    {
        deviceState = DEVICE_SHUTDOWN;
    }
    else if(isActitiyDetected)
    {
        deviceState = DEVICE_ACTIVE;
    }
}

#endif /* ENABLE_SYSTEM_DEEP_SLEEP */
/*****************************************************************************
* Function Name: Device_FW_Stop()
******************************************************************************
* Summary:
* This function is to stop all the device functionality and put the mcu in hibernate mode
*
* Parameters:
* None
*
* Return:
* None
*
* Theory:
* Stop all the modules and enter into lowest power mode. The only way to 
* get out of this state is to reset the device
*
* Side Effects:
* deviceState is updated
* 
* Note:
* Only a reset can get the system out of this mode
*****************************************************************************/
static void Device_FW_Stop(void)
{
    Timer_Stop();
    Watch_Dog_Timer_Disable();
    Device_ShutDown();
    while(1)
    {
        //CySysPmStop();
        CySysPmHibernate();
    }
}

/*****************************************************************************
* Function Name: main()
******************************************************************************
* Summary:
* This function maintains various power modes for the device
*
*
* Parameters:
* None
*
* Return:
* None
*
* Theory:
* The firmware supports following 5 modes:
* 1. Active mode 
* 2. Idle mode
* 3. Sleep mode
* 4. Deep Sleep mode
* 5. Shutdown mode 
* It is the responsibility of the device.c to determine the behaviour and 
* the time interval to be in the mode
* 
* 
* Side Effects:
* None
* 
* Note:
* None
*****************************************************************************/
int main()
{
    Device_FW_Init();
    for(;;)
    {
        switch(deviceState)
        {
            case DEVICE_ACTIVE:
                Device_FW_Active();
                break;
            case DEVICE_IDLE:
                Device_FW_Idle();
                break;
            case DEVICE_SLEEP:
                Device_FW_Sleep();
                break;
#ifdef ENABLE_SYSTEM_DEEP_SLEEP
            case DEVICE_DEEP_SLEEP:
                Device_FW_DeepSleep();
                break;
#endif /* ENABLE_SYSTEM_DEEP_SLEEP */
            case DEVICE_SHUTDOWN:
                Device_FW_Stop();
                break;
            default:
                break;
        }
    }
}
